﻿using Delphi.Janus.Util;
using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Web;


namespace Delphi.Isis.Yahoo {
    public class YahooScraper {
        private static string baseUrl = "http://finance.yahoo.com/q/";
        private static string incomeStatementUrl = "is?s=";
        private static string balanceSheetUrl = "bs?s=";
        private static string cashFlowUrl = "cf?s=";
        private static string annual = "&annual";
        private static string analystEstimateUrl = "ae?s=";

        public static List<YahooIncomeStatement> GetIncomeStatement(string yahooCode, bool isAnnual) {
            List<YahooIncomeStatement> incomeStatements = new List<YahooIncomeStatement>();
            string url = baseUrl + incomeStatementUrl + yahooCode;
            if (isAnnual) {
                url = url + annual;
            }

            HtmlDocument html = new HtmlDocument();
            html.LoadHtml(new WebClient().DownloadString(url));
            HtmlNode root = html.DocumentNode;

            HtmlNode masterTable;
            try {
                // Master Table which contains all data
                masterTable = root.Descendants()
                   .Where(n => n.GetAttributeValue("class", "").Equals("yfnc_tabledata1"))
                   .First()
                   .Descendants("table")
                   .First();
            } catch (Exception e) {
                return null;
            }


            // get the dates: <th>Dec 31, 2015</th>
            IEnumerable<HtmlNode> rows = masterTable.Descendants("th");
            foreach (var cell in rows) {
                YahooIncomeStatement yis = new YahooIncomeStatement();
                string text = HttpUtility.HtmlDecode(cell.InnerText);
                yis.Date = DateTime.ParseExact(text, "MMM d, yyyy", CultureInfo.InvariantCulture);
                yis.Period = isAnnual ? "Year" : "Quarter";
                yis.YahooCode = yahooCode;
                incomeStatements.Add(yis);
            }

            // get the data
            rows = masterTable.Descendants("tr");
            bool process = false;
            foreach (var row in rows) {

                IEnumerable<HtmlNode> cells = row.Descendants("td");
                string[] line = new string[incomeStatements.Count + 1];

                int counter = 0;

                foreach (var cell in cells) {
                    string text = HttpUtility.HtmlDecode(cell.InnerText).Trim();

                    if (!string.IsNullOrEmpty(text) & (cells.Count() >= incomeStatements.Count + 1)) {
                        line[counter] = text;
                        ++counter;
                        process = true;
                    }
                }

                if (process) {
                    for (int i = 1; i < line.Count(); ++i) {
                        /*if (line[0].Equals("Total Revenue")) {
                            incomeStatements.ElementAt(i - 1).TotalRevenue = int.Parse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"));
                        } else if () */

                        int amount = 0;
                        switch (line[0]) {
                            case "Total Revenue":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).TotalRevenue = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).TotalRevenue = 0;
                                }
                                break;

                            case "Cost of Revenue":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).CostOfRevenue = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).CostOfRevenue = 0;
                                }
                                break;

                            case "Gross Profit":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).GrossProfit = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).GrossProfit = 0;
                                }
                                break;

                            case "Research Development":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).RandD = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).RandD = 0;
                                }
                                break;

                            case "Selling General and Administrative":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).SGA = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).SGA = 0;
                                }
                                break;

                            case "Non Recurring":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).NonRecurring = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).NonRecurring = 0;
                                }
                                break;

                            case "Others":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).OtherExpenses = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).OtherExpenses = 0;
                                }
                                break;

                            case "Total Operating Expenses":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).TotalOpex = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).TotalOpex = 0;
                                }
                                break;

                            case "Operating Income or Loss":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).OperatingIncome = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).OperatingIncome = 0;
                                }
                                break;

                            case "Total Other Income/Expenses Net":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).TotalOtherIncome = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).TotalOtherIncome = 0;
                                }
                                break;

                            case "Earnings Before Interest And Taxes":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).Ebit = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).Ebit = 0;
                                }
                                break;

                            case "Interest Expense":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).InterestExpense = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).InterestExpense = 0;
                                }
                                break;

                            case "Income Before Tax":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).Ebt = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).Ebt = 0;
                                }
                                break;

                            case "Income Tax Expense":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).IncomeTaxExpenses = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).IncomeTaxExpenses = 0;
                                }
                                break;

                            case "Minority Interest":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).MinorityInterest = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).MinorityInterest = 0;
                                }
                                break;

                            case "Net Income From Continuing Ops":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).NiFromContinuingOps = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).NiFromContinuingOps = 0;
                                }
                                break;

                            case "Discontinued Operations":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).DiscontinuedOps = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).DiscontinuedOps = 0;
                                }
                                break;

                            case "Extraordinary Items":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).ExtraordinaryItems = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).ExtraordinaryItems = 0;
                                }
                                break;

                            case "Effect Of Accounting Changes":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).EffectOfAccountingChanges = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).EffectOfAccountingChanges = 0;
                                }
                                break;

                            case "Other Items":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).OtherItems = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).OtherItems = 0;
                                }
                                break;

                            case "Net Income":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).NetIncome = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).NetIncome = 0;
                                }
                                break;

                            case "Preferred Stock And Other Adjustments":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).PreferredStockAndOtherAdjustments = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).PreferredStockAndOtherAdjustments = 0;
                                }
                                break;

                            case "Net Income Applicable To Common Shares":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    incomeStatements.ElementAt(i - 1).NiAttributableToCommon = amount;
                                } else {
                                    incomeStatements.ElementAt(i - 1).NiAttributableToCommon = 0;
                                }
                                break;
                        }
                    }
                    process = false;
                }
            }
            return incomeStatements;
        }

        public static List<YahooBalanceSheet> GetBalanceSheet(string yahooCode, bool isAnnual) {
            List<YahooBalanceSheet> balanceSheets = new List<YahooBalanceSheet>();
            string url = baseUrl + balanceSheetUrl + yahooCode;
            if (isAnnual) {
                url = url + annual;
            }

            HtmlDocument html = new HtmlDocument();
            html.LoadHtml(new WebClient().DownloadString(url));
            HtmlNode root = html.DocumentNode;

            HtmlNode masterTable;
            try {
                // Master Table which contains all data
                masterTable = root.Descendants()
                   .Where(n => n.GetAttributeValue("class", "").Equals("yfnc_tabledata1"))
                   .First()
                   .Descendants("table")
                   .First();
            } catch (Exception e) {
                return null;
            }

            // get the dates: <th>Dec 31, 2015</th>
            IEnumerable<HtmlNode> rows = masterTable.Descendants()
                .Where(n => n.GetAttributeValue("class", "").Equals("yfnc_modtitle1"));

            foreach (var cell in rows) {
                YahooBalanceSheet ybs = new YahooBalanceSheet();
                string text = HttpUtility.HtmlDecode(cell.InnerText);
                try {
                    ybs.Date = DateTime.ParseExact(text, "MMM d, yyyy", CultureInfo.InvariantCulture);
                    ybs.Period = isAnnual ? "Annual" : "Quarterly";
                    ybs.YahooCode = yahooCode;
                    balanceSheets.Add(ybs);
                } catch (Exception e) {
                    continue;
                }

            }

            // get the data
            rows = masterTable.Descendants("tr");
            bool process = false;
            foreach (var row in rows) {

                IEnumerable<HtmlNode> cells = row.Descendants("td");
                string[] line = new string[balanceSheets.Count + 1];

                int counter = 0;

                foreach (var cell in cells) {
                    string text = HttpUtility.HtmlDecode(cell.InnerText).Trim();

                    if (!string.IsNullOrEmpty(text) & (cells.Count() >= balanceSheets.Count + 1)) {
                        line[counter] = text;
                        ++counter;
                        process = true;
                    }
                }

                if (process) {
                    for (int i = 1; i < line.Count(); ++i) {
                        /*if (line[0].Equals("Total Revenue")) {
                            incomeStatements.ElementAt(i - 1).TotalRevenue = int.Parse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"));
                        } else if () */

                        int amount = 0;
                        switch (line[0]) {
                            case "Cash And Cash Equivalents":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).CashAndEquivalents = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).CashAndEquivalents = 0;
                                }
                                break;

                            case "Short Term Investments":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).ShortTermInvestments = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).ShortTermInvestments = 0;
                                }
                                break;

                            case "Net Receivables":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).NetReceivables = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).NetReceivables = 0;
                                }
                                break;

                            case "Inventorys":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).Inventory = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).Inventory = 0;
                                }
                                break;

                            case "Other Current Assets":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).OtherCurrentAssets = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).OtherCurrentAssets = 0;
                                }
                                break;

                            case "Total Current Assets":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).TotalCurrentAssets = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).TotalCurrentAssets = 0;
                                }
                                break;

                            case "Long Term Investments":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).LongTermInvestments = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).LongTermInvestments = 0;
                                }
                                break;

                            case "Property Plant and Equipment":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).Ppe = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).Ppe = 0;
                                }
                                break;

                            case "Goodwill":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).Goodewill = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).Goodewill = 0;
                                }
                                break;

                            case "Intangible Assets":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).IntangibleAssets = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).IntangibleAssets = 0;
                                }
                                break;

                            case "Accumulated Amortization":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).AccumulatedAmort = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).AccumulatedAmort = 0;
                                }
                                break;

                            case "Other Assets":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).OtherAssets = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).OtherAssets = 0;
                                }
                                break;

                            case "Deferred Long Term Asset Charges":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).DeferredLtAssetCharges = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).DeferredLtAssetCharges = 0;
                                }
                                break;

                            case "Total Assets":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).TotalAssets = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).TotalAssets = 0;
                                }
                                break;

                            case "Accounts Payable":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).AccountsPayable = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).AccountsPayable = 0;
                                }
                                break;

                            case "Short/Current Long Term Debt":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).CurrentDebt = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).CurrentDebt = 0;
                                }
                                break;

                            case "Other Current Liabilities":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).OtherCurrentLiabilities = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).OtherCurrentLiabilities = 0;
                                }
                                break;

                            case "Total Current Liabilities":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).TotalCurrentLiabilities = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).TotalCurrentLiabilities = 0;
                                }
                                break;

                            case "Long Term Debt":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).LongTermDebt = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).LongTermDebt = 0;
                                }
                                break;

                            case "Other Liabilities":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).OtherLtLiabilities = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).OtherLtLiabilities = 0;
                                }
                                break;

                            case "Deferred Long Term Liability Charges":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).DefferLtLiabilitiesCharges = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).DefferLtLiabilitiesCharges = 0;
                                }
                                break;

                            case "Minority Interest":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).MinorityInterest = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).MinorityInterest = 0;
                                }
                                break;

                            case "Negative Goodwill":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).NegativeGoodwill = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).NegativeGoodwill = 0;
                                }
                                break;

                            case "Total Liabilities":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).TotalLiabilities = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).TotalLiabilities = 0;
                                }
                                break;

                            case "Misc Stocks Options Warrants":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).StockWarrants = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).StockWarrants = 0;
                                }
                                break;

                            case "Redeemable Preferred Stock":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).RedeemablePreferredStock = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).RedeemablePreferredStock = 0;
                                }
                                break;

                            case "Preferred Stock":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).PreferredStock = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).PreferredStock = 0;
                                }
                                break;

                            case "Common Stock":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).CommonStock = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).CommonStock = 0;
                                }
                                break;

                            case "Retained Earnings":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).RetainedEarnings = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).RetainedEarnings = 0;
                                }
                                break;

                            case "Treasury Stock":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).TreasuryStock = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).TreasuryStock = 0;
                                }
                                break;

                            case "Capital Surplus":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).CapitalSurplus = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).CapitalSurplus = 0;
                                }
                                break;

                            case "Other Stockholder Equity":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).OtherStockholderEquity = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).OtherStockholderEquity = 0;
                                }
                                break;

                            case "Total Stockholder Equity":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).TotalStockholderEquity = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).TotalStockholderEquity = 0;
                                }
                                break;

                            case "Net Tangible Assets":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    balanceSheets.ElementAt(i - 1).NetTangibleAssets = amount;
                                } else {
                                    balanceSheets.ElementAt(i - 1).NetTangibleAssets = 0;
                                }
                                break;
                        }
                    }
                    process = false;
                }
            }
            return balanceSheets;
        }

        public static List<YahooCashFlow> GetCashFlow(string yahooCode, bool isAnnual) {
            List<YahooCashFlow> cashFlows = new List<YahooCashFlow>();
            string url = baseUrl + cashFlowUrl + yahooCode;
            if (isAnnual) {
                url = url + annual;
            }

            HtmlDocument html = new HtmlDocument();
            html.LoadHtml(new WebClient().DownloadString(url));
            HtmlNode root = html.DocumentNode;

            HtmlNode masterTable;
            try {
                // Master Table which contains all data
                masterTable = root.Descendants()
                   .Where(n => n.GetAttributeValue("class", "").Equals("yfnc_tabledata1"))
                   .First()
                   .Descendants("table")
                   .First();
            } catch (Exception e) {
                return null;
            }

            // get the dates: <th>Dec 31, 2015</th>
            IEnumerable<HtmlNode> rows = masterTable.Descendants()
                .Where(n => n.GetAttributeValue("class", "").Equals("yfnc_modtitle1"));
            foreach (var cell in rows) {
                YahooCashFlow ycf = new YahooCashFlow();
                string text = HttpUtility.HtmlDecode(cell.InnerText);
                try {
                    ycf.Date = DateTime.ParseExact(text, "MMM d, yyyy", CultureInfo.InvariantCulture);
                    ycf.Period = isAnnual ? "Annual" : "Quarterly";
                    ycf.YahooCode = yahooCode;
                    cashFlows.Add(ycf);
                } catch (Exception e) {
                    continue;
                }
            }

            // get the data
            rows = masterTable.Descendants("tr");
            bool process = false;
            foreach (var row in rows) {

                IEnumerable<HtmlNode> cells = row.Descendants("td");
                string[] line = new string[cashFlows.Count + 1];

                int counter = 0;

                foreach (var cell in cells) {
                    string text = HttpUtility.HtmlDecode(cell.InnerText).Trim();

                    if (!string.IsNullOrEmpty(text) & (cells.Count() >= cashFlows.Count + 1)) {
                        line[counter] = text;
                        ++counter;
                        process = true;
                    }
                }

                if (process) {
                    for (int i = 1; i < line.Count(); ++i) {
                        /*if (line[0].Equals("Total Revenue")) {
                            incomeStatements.ElementAt(i - 1).TotalRevenue = int.Parse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"));
                        } else if () */

                        int amount = 0;
                        switch (line[0]) {
                            case "Depreciation":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    cashFlows.ElementAt(i - 1).Depretiation = amount;
                                } else {
                                    cashFlows.ElementAt(i - 1).Depretiation = 0;
                                }
                                break;

                            case "Adjustments To Net Income":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    cashFlows.ElementAt(i - 1).AdjustmentsNi = amount;
                                } else {
                                    cashFlows.ElementAt(i - 1).AdjustmentsNi = 0;
                                }
                                break;

                            case "Changes In Accounts Receivables":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    cashFlows.ElementAt(i - 1).ChangesReceivables = amount;
                                } else {
                                    cashFlows.ElementAt(i - 1).ChangesReceivables = 0;
                                }
                                break;

                            case "Changes In Liabilities":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    cashFlows.ElementAt(i - 1).ChangesLiabilities = amount;
                                } else {
                                    cashFlows.ElementAt(i - 1).ChangesLiabilities = 0;
                                }
                                break;

                            case "Changes In Inventories":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    cashFlows.ElementAt(i - 1).ChangesInventories = amount;
                                } else {
                                    cashFlows.ElementAt(i - 1).ChangesInventories = 0;
                                }
                                break;

                            case "Changes In Other Operating Activities":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    cashFlows.ElementAt(i - 1).ChangesOtherOps = amount;
                                } else {
                                    cashFlows.ElementAt(i - 1).ChangesOtherOps = 0;
                                }
                                break;

                            case "Total Cash Flow From Operating Activities":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    cashFlows.ElementAt(i - 1).TotalCfo = amount;
                                } else {
                                    cashFlows.ElementAt(i - 1).TotalCfo = 0;
                                }
                                break;

                            case "Capital Expenditures":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    cashFlows.ElementAt(i - 1).CapEx = amount;
                                } else {
                                    cashFlows.ElementAt(i - 1).CapEx = 0;
                                }
                                break;

                            case "Investments":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    cashFlows.ElementAt(i - 1).Investments = amount;
                                } else {
                                    cashFlows.ElementAt(i - 1).Investments = 0;
                                }
                                break;

                            case "Other Cash flows from Investing Activities":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    cashFlows.ElementAt(i - 1).OtherInvesting = amount;
                                } else {
                                    cashFlows.ElementAt(i - 1).OtherInvesting = 0;
                                }
                                break;

                            case "Total Cash Flows From Investing Activities":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    cashFlows.ElementAt(i - 1).TotalCfi = amount;
                                } else {
                                    cashFlows.ElementAt(i - 1).TotalCfi = 0;
                                }
                                break;

                            case "Dividends Paid":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    cashFlows.ElementAt(i - 1).DividendsPaid = amount;
                                } else {
                                    cashFlows.ElementAt(i - 1).DividendsPaid = 0;
                                }
                                break;

                            case "Sale Purchase of Stock":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    cashFlows.ElementAt(i - 1).SalePurchaseStock = amount;
                                } else {
                                    cashFlows.ElementAt(i - 1).SalePurchaseStock = 0;
                                }
                                break;

                            case "Net Borrowings":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    cashFlows.ElementAt(i - 1).NetBorrowings = amount;
                                } else {
                                    cashFlows.ElementAt(i - 1).NetBorrowings = 0;
                                }
                                break;

                            case "Other Cash Flows from Financing Activities":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    cashFlows.ElementAt(i - 1).OtherFinancing = amount;
                                } else {
                                    cashFlows.ElementAt(i - 1).OtherFinancing = 0;
                                }
                                break;

                            case "Total Cash Flows From Financing Activities":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    cashFlows.ElementAt(i - 1).TotalCff = amount;
                                } else {
                                    cashFlows.ElementAt(i - 1).TotalCff = 0;
                                }
                                break;

                            case "Effect Of Exchange Rate Change":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    cashFlows.ElementAt(i - 1).EffectFxRateChangess = amount;
                                } else {
                                    cashFlows.ElementAt(i - 1).EffectFxRateChangess = 0;
                                }
                                break;

                            case "Change In Cash and Cash Equivalents":
                                if (int.TryParse(line[i], NumberStyles.AllowThousands | NumberStyles.AllowParentheses, new CultureInfo("en-US"), out amount)) {
                                    cashFlows.ElementAt(i - 1).ChangeCashAndEquivalents = amount;
                                } else {
                                    cashFlows.ElementAt(i - 1).ChangeCashAndEquivalents = 0;
                                }
                                break;
                        }
                    }
                    process = false;
                }
            }
            return cashFlows;
        }

        public static List<YahooAnalystEstimates> GetAnalystEstimate(string yahooCode) {
            List<YahooAnalystEstimates> analystEstimate = new List<YahooAnalystEstimates>();
            string url = baseUrl + analystEstimateUrl + yahooCode;

            // Hmm, hard coded number --> potential exception....
            YahooAnalystEstimates[] ae = new YahooAnalystEstimates[4];
            for(int i = 0; i < ae.Count(); i++) {
                ae[i] = new YahooAnalystEstimates();
                ae[i].YahooCode = yahooCode;
            }
           

            HtmlDocument html = new HtmlDocument();
            html.LoadHtml(new WebClient().DownloadString(url));
            HtmlNode root = html.DocumentNode;
            string s;
            var test = root.Descendants("td");
            DateTime nextEraningsDate = new DateTime();
            try {
                foreach (var t in test) {
                    if (t.InnerText.StartsWith("Next Earnings Date: ")) {
                        s = t.InnerText.Replace("Next Earnings Date: ", "").GetFirst(12).Trim();
                        nextEraningsDate = DateTime.ParseExact(s, "MMM dd, yyyy", new CultureInfo("en-US"));
                        break;
                    } else if(t.InnerText.StartsWith("There is no Analyst Estimates data available")) {
                        return null;
                    }
                }
            } catch (Exception e) {
                
            }

            // get all the tables with data that needs to be extracted
            IEnumerable<HtmlNode> masterTable;
            try {
                // Master Table which contains all data
                masterTable = root.Descendants("table")
                .Where(n => n.GetAttributeValue("class", "").Equals("yfnc_tableout1"));
            } catch (Exception e) {
                return null;
            }

            if(masterTable.Count() == 0) {
                return null;
            }

            foreach (var tab in masterTable) {
                // Get the headings of table ...
                var headings = tab.Descendants("th");
                string[] headingElements = new string[headings.Count()];

                // and get the respective rows
                var rows = tab.Descendants("tr");
                string[] rowElements = new string[headings.Count()];

                int counter = 0;
                foreach (var heading in headings) {
                    headingElements[counter++] = heading.InnerText;
                }

                DateTime date = new DateTime();

                switch (headingElements[0]) {
                    case "Earnings Est":
                        // don't need element at position 0
                        for (int i = 1; i < headingElements.Count(); ++i) {
                            // get the date part --> last 6 char in string
                            try {
                                date = DateTime.ParseExact(headingElements[i].GetLast(6), "MMM yy", new CultureInfo("en-US"));
                            } catch (Exception) {
                                return null;
                            }
                            ae[i - 1].EarningsEstimateDate = date.AddDays(DateTime.DaysInMonth(date.Year, date.Month) - 1);
                            ae[i - 1].NextEarningsDate = nextEraningsDate;
                            // remove date part --> remove last 6 chars in string
                            string lable = headingElements[i].RemoveLast(6);
                            switch (lable) {
                                case "Current Qtr.":
                                    ae[i - 1].EarningsEstimatesCurrent = true;
                                    ae[i - 1].EarningsEstimatePeriod = "Quarter";
                                    break;
                                case "Next Qtr.":
                                    ae[i - 1].EarningsEstimatesCurrent = false;
                                    ae[i - 1].EarningsEstimatePeriod = "Quarter";
                                    break;
                                case "Current Year":
                                    ae[i - 1].EarningsEstimatesCurrent = true;
                                    ae[i - 1].EarningsEstimatePeriod = "Year";
                                    break;
                                case "Next Year":
                                    ae[i - 1].EarningsEstimatesCurrent = false;
                                    ae[i - 1].EarningsEstimatePeriod = "Year";
                                    break;
                            }
                        }
                        break;

                    case "Revenue Est":
                        for (int i = 1; i < headingElements.Count(); ++i) {
                            // get the date part --> last 6 char in string
                            date = DateTime.ParseExact(headingElements[i].GetLast(6), "MMM yy", new CultureInfo("en-US"));
                            ae[i - 1].RevenueEstimateDate = date.AddDays(DateTime.DaysInMonth(date.Year, date.Month) - 1);
                            // remove date part --> remove last 6 chars in string
                            string lable = headingElements[i].RemoveLast(6);
                            switch (lable) {
                                case "Current Qtr.":
                                    ae[i - 1].RevenueEstimateCurrent = true;
                                    ae[i - 1].RevenueEstimatePeriod = "Quarter";
                                    break;
                                case "Next Qtr.":
                                    ae[i - 1].RevenueEstimateCurrent = false;
                                    ae[i - 1].RevenueEstimatePeriod = "Quarter";
                                    break;
                                case "Current Year":
                                    ae[i - 1].RevenueEstimateCurrent = true;
                                    ae[i - 1].RevenueEstimatePeriod = "Year";
                                    break;
                                case "Next Year":
                                    ae[i - 1].RevenueEstimateCurrent = false;
                                    ae[i - 1].RevenueEstimatePeriod = "Year";
                                    break;
                            }
                        }
                        break;

                    case "Earnings History":
                        for (int i = 1; i < headingElements.Count(); ++i) {
                            // get the date part --> last 6 char in string
                            try {
                                date = DateTime.ParseExact(headingElements[i].GetLast(6), "MMM yy", new CultureInfo("en-US"));
                            } catch (Exception) {
                                return null;
                            }
                            ae[i - 1].EarningsHistoryDate = date.AddDays(DateTime.DaysInMonth(date.Year, date.Month) - 1);
                        }
                        break;

                    case "EPS Trends":
                        for (int i = 1; i < headingElements.Count(); ++i) {
                            // get the date part --> last 6 char in string
                            date = DateTime.ParseExact(headingElements[i].GetLast(6), "MMM yy", new CultureInfo("en-US"));
                            ae[i - 1].EpsTrendDate = date.AddDays(DateTime.DaysInMonth(date.Year, date.Month) - 1);
                            // remove date part --> remove last 6 chars in string
                            string lable = headingElements[i].RemoveLast(6);
                            switch (lable) {
                                case "Current Qtr.":
                                    ae[i - 1].EpsTrendsCurrent = true;
                                    ae[i - 1].EpsTrendsPeriod = "Quarter";
                                    break;
                                case "Next Qtr.":
                                    ae[i - 1].EpsTrendsCurrent = false;
                                    ae[i - 1].EpsTrendsPeriod = "Quarter";
                                    break;
                                case "Current Year":
                                    ae[i - 1].EpsTrendsCurrent = true;
                                    ae[i - 1].EpsTrendsPeriod = "Year";
                                    break;
                                case "Next Year":
                                    ae[i - 1].EpsTrendsCurrent = false;
                                    ae[i - 1].EpsTrendsPeriod = "Year";
                                    break;
                            }
                        }
                        break;

                    case "EPS Revisions":
                        for (int i = 1; i < headingElements.Count(); ++i) {
                            // get the date part --> last 6 char in string
                            date = DateTime.ParseExact(headingElements[i].GetLast(6), "MMM yy", new CultureInfo("en-US"));
                            ae[i - 1].EpsRevisionDate = date.AddDays(DateTime.DaysInMonth(date.Year, date.Month) - 1);
                            // remove date part --> remove last 6 chars in string
                            string lable = headingElements[i].RemoveLast(6);
                            switch (lable) {
                                case "Current Qtr.":
                                    ae[i - 1].EpsRevisionsCurrent = true;
                                    ae[i - 1].EpsRevisionsPeriod = "Quarter";
                                    break;
                                case "Next Qtr.":
                                    ae[i - 1].EpsRevisionsCurrent = false;
                                    ae[i - 1].EpsRevisionsPeriod = "Quarter";
                                    break;
                                case "Current Year":
                                    ae[i - 1].EpsRevisionsCurrent = true;
                                    ae[i - 1].EpsRevisionsPeriod = "Year";
                                    break;
                                case "Next Year":
                                    ae[i - 1].EpsRevisionsCurrent = false;
                                    ae[i - 1].EpsRevisionsPeriod = "Year";
                                    break;
                            }
                        }
                        break;

                    case "Growth Est":
                        for (int i = 1; i < headingElements.Count(); ++i) {
                            ae[i - 1].GrowthEstimateType = HttpUtility.HtmlDecode(headingElements[i]);
                        }
                        break;
                } // switch headings


                foreach (var row in rows) {
                    var cells = row.Descendants("td");
                    bool rowLableFlag = true;
                    counter = 0;
                    string rowLable = "";
                    Decimal amountDec = 0;
                    int amountInt = 0;

                    foreach (var cell in cells) {
                        if (rowLableFlag) {
                            rowLable = HttpUtility.HtmlDecode(cell.InnerText);
                            rowLableFlag = false;
                            continue;
                        }
                        counter++;
                        switch (headingElements[0]) {
                            case "Earnings Est":
                                switch (rowLable) {
                                    case "Avg. Estimate":
                                        if (Decimal.TryParse(cell.InnerText, NumberStyles.Any, new CultureInfo("en-US"), out amountDec)) {
                                            ae[counter - 1].EarningsEstimateAverage = amountDec;
                                        } else {
                                            ae[counter - 1].EarningsEstimateAverage = 0;
                                        }
                                        break;

                                    case "No. of Analysts":
                                        if (Decimal.TryParse(cell.InnerText, NumberStyles.Any, new CultureInfo("en-US"), out amountDec)) {
                                            ae[counter - 1].EarningsEstimateNof = amountDec;
                                        } else {
                                            ae[counter - 1].EarningsEstimateNof = 0;
                                        }
                                        break;

                                    case "Low Estimate":
                                        if (Decimal.TryParse(cell.InnerText, NumberStyles.Any, new CultureInfo("en-US"), out amountDec)) {
                                            ae[counter - 1].EarningsEstimateLow = amountDec;
                                        } else {
                                            ae[counter - 1].EarningsEstimateLow = 0;
                                        }
                                        break;

                                    case "High Estimate":
                                        if (Decimal.TryParse(cell.InnerText, NumberStyles.Any, new CultureInfo("en-US"), out amountDec)) {
                                            ae[counter - 1].EarningsEstimateHigh = amountDec;
                                        } else {
                                            ae[counter - 1].EarningsEstimateHigh = 0;
                                        }
                                        break;

                                    case "Year Ago EPS":
                                        if (Decimal.TryParse(cell.InnerText, NumberStyles.Any, new CultureInfo("en-US"), out amountDec)) {
                                            ae[counter - 1].EarningsEstimateYearAgo = amountDec;
                                        } else {
                                            ae[counter - 1].EarningsEstimateYearAgo = 0;
                                        }
                                        break;
                                }
                                break; // Earnings Est

                            case "Revenue Est":
                                switch (rowLable) {
                                    case "Avg. Estimate":
                                        ae[counter - 1].RevenueEstimateAvg = cell.InnerText.YahooConvert();
                                        break;
                                    case "No. of Analysts":
                                        if (Decimal.TryParse(cell.InnerText, NumberStyles.Any, new CultureInfo("en-US"), out amountDec)) {
                                            ae[counter - 1].RevenueEstimateNof = amountDec;
                                        } else {
                                            ae[counter - 1].RevenueEstimateNof = 0;
                                        }
                                        break;
                                    case "Low Estimate":
                                        ae[counter - 1].RevenueEstimateLow = cell.InnerText.YahooConvert();
                                        break;
                                    case "High Estimate":
                                        ae[counter - 1].RevenueEstimateHigh = cell.InnerText.YahooConvert();
                                        break;
                                    case "Year Ago Sales":
                                        ae[counter - 1].RevenueEstimateYearAgo = cell.InnerText.YahooConvert();
                                        break;
                                    case "Sales Growth (year/est)":
                                        ae[counter - 1].RevenueEstimateSalesGrowth = cell.InnerText.YahooConvert();
                                        break;
                                }
                                break; // Revenue Est

                            case "Earnings History":
                                switch (rowLable) {
                                    case "EPS Est":
                                        if (Decimal.TryParse(cell.InnerText, NumberStyles.Any, new CultureInfo("en-US"), out amountDec)) {
                                            ae[counter - 1].EarningsHistoryEstimate = amountDec;
                                        } else {
                                            ae[counter - 1].EarningsHistoryEstimate = 0;
                                        }
                                        break;
                                    case "EPS Actual":
                                        if (Decimal.TryParse(cell.InnerText, NumberStyles.Any, new CultureInfo("en-US"), out amountDec)) {
                                            ae[counter - 1].EarningsHistoryActuals = amountDec;
                                        } else {
                                            ae[counter - 1].EarningsHistoryActuals = 0;
                                        }
                                        break;
                                    case "Difference":
                                        if (Decimal.TryParse(cell.InnerText, NumberStyles.Any, new CultureInfo("en-US"), out amountDec)) {
                                            ae[counter - 1].EarningsHistoryDifference = amountDec;
                                        } else {
                                            ae[counter - 1].EarningsHistoryDifference = 0;
                                        }
                                        break;
                                    case "Surprise %":
                                        ae[counter - 1].EarningsHistorySurprise = cell.InnerText.YahooConvert();
                                        break;
                                }
                                break; // Earnings Hostory

                            case "EPS Trends":
                                switch (rowLable) {
                                    case "Current Estimate":
                                        if (Decimal.TryParse(cell.InnerText, NumberStyles.Any, new CultureInfo("en-US"), out amountDec)) {
                                            ae[counter - 1].EpsTrendsCurrentEstimate = amountDec;
                                        } else {
                                            ae[counter - 1].EpsTrendsCurrentEstimate = 0;
                                        }
                                        break;
                                    case "7 Days Ago":
                                        if (Decimal.TryParse(cell.InnerText, NumberStyles.Any, new CultureInfo("en-US"), out amountDec)) {
                                            ae[counter - 1].EpsTrends7DaysAgo = amountDec;
                                        } else {
                                            ae[counter - 1].EpsTrends7DaysAgo = 0;
                                        }
                                        break;
                                    case "30 Days Ago":
                                        if (Decimal.TryParse(cell.InnerText, NumberStyles.Any, new CultureInfo("en-US"), out amountDec)) {
                                            ae[counter - 1].EpsTrends30DaysAgo = amountDec;
                                        } else {
                                            ae[counter - 1].EpsTrends30DaysAgo = 0;
                                        }
                                        break;
                                    case "60 Days Ago":
                                        if (Decimal.TryParse(cell.InnerText, NumberStyles.Any, new CultureInfo("en-US"), out amountDec)) {
                                            ae[counter - 1].EpsTrends60DaysAgo = amountDec;
                                        } else {
                                            ae[counter - 1].EpsTrends60DaysAgo = 0;
                                        }
                                        break;
                                    case "90 Days Ago":
                                        if (Decimal.TryParse(cell.InnerText, NumberStyles.Any, new CultureInfo("en-US"), out amountDec)) {
                                            ae[counter - 1].EpsTrends90DaysAgo = amountDec;
                                        } else {
                                            ae[counter - 1].EpsTrends90DaysAgo = 0;
                                        }
                                        break;
                                }
                                break; // EPS Trends

                            case "EPS Revisions":
                                switch (rowLable) {
                                    case "Up Last 7 Days":
                                        if (int.TryParse(cell.InnerText, NumberStyles.Any, new CultureInfo("en-US"), out amountInt)) {
                                            ae[counter - 1].EpsRevisionsUp7Days = amountInt;
                                        } else {
                                            ae[counter - 1].EpsRevisionsUp7Days = 0;
                                        }
                                        break;
                                    case "Up Last 30 Days":
                                        if (int.TryParse(cell.InnerText, NumberStyles.Any, new CultureInfo("en-US"), out amountInt)) {
                                            ae[counter - 1].EpsRevisionsUp30Days = amountInt;
                                        } else {
                                            ae[counter - 1].EpsRevisionsUp30Days = 0;
                                        }
                                        break;
                                    case "Down Last 30 Days":
                                        if (int.TryParse(cell.InnerText, NumberStyles.Any, new CultureInfo("en-US"), out amountInt)) {
                                            ae[counter - 1].EpsRevisionsDown30Days = amountInt;
                                        } else {
                                            ae[counter - 1].EpsRevisionsDown30Days = 0;
                                        }
                                        break;
                                    case "Down Last 90 Days":
                                        if (int.TryParse(cell.InnerText, NumberStyles.Any, new CultureInfo("en-US"), out amountInt)) {
                                            ae[counter - 1].EpsRevisionsDown90Days = amountInt;
                                        } else {
                                            ae[counter - 1].EpsRevisionsDown90Days = 0;
                                        }
                                        break;
                                }
                                break; // EPS Revisions

                            case "Growth Est":
                                switch (rowLable) {
                                    case "Current Qtr.":
                                        ae[counter - 1].GrowthEstimateCurrentQuarter = cell.InnerText.YahooConvert();
                                        break;
                                    case "Next Qtr.":
                                        ae[counter - 1].GrowthEstimateNextQuarter = cell.InnerText.YahooConvert();
                                        break;
                                    case "This Year":
                                        ae[counter - 1].GrowthEstimateThisYear = cell.InnerText.YahooConvert();
                                        break;
                                    case "Next Year":
                                        ae[counter - 1].GrowthEstimateNextYear = cell.InnerText.YahooConvert();
                                        break;
                                    case "Past 5 Years (per annum)":
                                        ae[counter - 1].GrowthEstimatePast5Years = cell.InnerText.YahooConvert();
                                        break;
                                    case "Next 5 Years (per annum)":
                                        ae[counter - 1].GrowthEstimateNext5Years = cell.InnerText.YahooConvert();
                                        break;
                                    case "Price/Earnings (avg. for comparison categories)":
                                        ae[counter - 1].GrowthEstimatePe = cell.InnerText.YahooConvert();
                                        break;
                                    case "PEG Ratio (avg. for comparison categories)":
                                        ae[counter - 1].GrowthEstimatePeg = cell.InnerText.YahooConvert();
                                        break;
                                }
                                break; // Growth Est
                        } // switch headingsElemenmt
                    }
                }



            } // foreach mastertable
            
            return ae.ToList();
        }

        
    }
}
